using System;
using System.Collections.Generic;
using System.Reflection;
using Database.NHibernateInterface;
using Domain.Entities;
using Domain.Enums;
using Domain.Repositories;
using NHibernate;
using NHibernate.Cfg;
using System.Collections;
using NHibernate.Criterion;

namespace Database.Repositories
{
    public class UserRepository : BaseRepository<User>, IUserRepository
    {
        private readonly ISessionProvider sessionProvider;


        public UserRepository(ISessionProvider sessionProvider):base(sessionProvider)
        {
            this.sessionProvider = sessionProvider;
        }

        protected ISession Session
        {
            get { return sessionProvider.CurrentSession; }
        }

        #region IUserRepository Members

        public User GetUserByName(string userName, string appName)
        {
            var u = Session.CreateCriteria(typeof(User))
                        .Add(Restrictions.Eq("UserName", userName))
                        .UniqueResult() as User;
                return u;
        }

        public List<User> GetAllUsers(int pageIndex, int pageSize, string appName)
        {
            var users = new List<User>();
            users = Session.CreateCriteria(typeof(User))
                        .Add(Restrictions.Eq("ApplicationName", appName))
                        .SetFirstResult(pageIndex * pageSize).SetMaxResults(pageSize)
                        .List<User>() as List<User>;
            return users;
        }

        public int GetNumberOfUsersOnline(DateTime compareTime, string appName)
        {
            IList uList = Session.CreateCriteria(typeof(User))
                        .Add(Restrictions.Eq("ApplicationName", appName))
                        .Add(Restrictions.Ge("LastActivityDate", compareTime))
                        .List();
                    return uList.Count;
        }

        public bool IsAdmin(User candidate)
        {
            return candidate.Role == UserRoles.Administrator;
        }

        public void Update(List<User> users)
        {
            foreach (var user in users)
            {
                if (GetUserByName(user.UserName, "") == null && user.Role != UserRoles.Administrator)
                {
                    Save(user);
                }
            }
        }


        public string GetUserNameByEMail(string EMail, string appName)
        {
            IList uList = Session.CreateCriteria(typeof(User))
                        .Add(Expression.Eq("EMail", EMail))
                        .Add(Expression.Eq("ApplicationName", appName))
                        .List();
                    if (uList.Count > 0)
                    {
                        User u = (User)uList[0];
                        return u.UserName;
                    }
                    else
                    {
                        return String.Empty;
                    }
        }

        public List<User> FindUsersByEMail(string email, int pageIndex, int pageSize, string appName)
        {
            var users = new List<User>();
            users = Session.CreateCriteria(typeof(User))
                        .Add(Expression.Like("EMail", email, MatchMode.Anywhere))
                        .Add(Expression.Eq("ApplicationName", appName))
                        .SetFirstResult(pageIndex * pageSize).SetMaxResults(pageSize)
                        .List<User>() as List<User>;
            return users;
        }

        public List<User> FindUsersByName(string userName, int pageIndex, int pageSize, string appName)
        {
            var users = new List<User>();
            users = Session.CreateCriteria(typeof(User))
                        .Add(Expression.Like("UserName", userName, MatchMode.Anywhere))
                        .Add(Expression.Eq("ApplicationName", appName))
                        .SetFirstResult(pageIndex * pageSize).SetMaxResults(pageSize)
                        .List<User>() as List<User>;
            return users;
        }

        #endregion
    }
}
